package com.sxbbc.seller.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import com.sxbbc.common.core.entity.jz.*;
import com.sxbbc.common.core.service.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.function.common.GetRest;
import com.function.common.RestResponse;
import com.sxbbc.common.basics.exceptions.ThrowPageException;
import com.sxbbc.common.basics.exp.ExpDetailVo;
import com.sxbbc.common.basics.rest.RestFactory;
import com.sxbbc.common.basics.utils.calculation.CalcuUtils;
import com.sxbbc.common.basics.utils.statics.StaticUtils;
import com.sxbbc.common.core.dto.jz.PropertiesVo;
import com.sxbbc.common.core.enums.OrderStatusEnums;
import com.sxbbc.common.core.enums.OrderTypeEnums;
import com.sxbbc.common.core.enums.PayTypeEnums;
import com.sxbbc.common.core.enums.ReceivedTypeEnums;
import com.sxbbc.common.core.utils.BasePage;
import com.sxbbc.seller.common.OrderMapping;
import com.sxbbc.seller.util.BusinessSession;
import com.sxbbc.seller.util.SystemLog;

/**
 * 订单管理控制层
 *
 * @author xiaoky
 * @date 2019-05-14
 */
@Controller
public class OrderController {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private IOrderMainService orderMainService;
    @Autowired
    private IOrderRefundLogService orderRefundLogService;
    @Autowired
    private IOrderBasicExpService orderBasicExpService;
    @Autowired
    private IOrderExpDetailService orderExpDetailService;
    @Autowired
    private IProSkuDetailService proSkuDetailService;
    @Autowired
    private IProcMainService procMainService;
    @Autowired
    private IWWarehouseService warehouseService;
    @Autowired
    private IAddressService addressService;
    @Autowired
    private IOrderDetailService orderDetailService;

    /**
     * 订单列表页面
     *
     * @return ModelAndView
     * @author xiaoky
     */
    @RequestMapping(value = OrderMapping.SHOW_ORDER_LIST)
    public ModelAndView showOrderList() {
        ModelAndView view = new ModelAndView(OrderMapping.SHOW_ORDER_LIST);
        // 订单类型
        List<OrderTypeEnums> typeList = OrderTypeEnums.queryValidList();
        // 订单状态
        List<OrderStatusEnums> statusList = OrderStatusEnums.queryList();
        // 支付方式
        List<PayTypeEnums> payTypeList = PayTypeEnums.queryList();

        view.addObject("typeList", typeList);
        view.addObject("statusList", statusList);
        view.addObject("payTypeList", payTypeList);
        return view;
    }

    /**
     * 查询订单列表数据
     *
     * @param page      分页
     * @param orderMain 查询数据
     * @return
     * @author xiaoky
     */
    @RequestMapping(value = OrderMapping.QUERY_ORDER_LIST)
    @ResponseBody
    public com.sxbbc.common.basics.rest.RestResponse queryOrderList(BasePage<OrderMain> page, OrderMain orderMain) {
        Integer bid = BusinessSession.getBid(request);
        orderMain.setBid(bid);
        // 查询未删除的订单
        orderMain.setDel(StaticUtils.STATUS_NO);
        // 订单列表
        orderMainService.queryOrder(page, orderMain);
        return RestFactory.success(page.getRecords(), page.getTotal());
    }

    /**
     * 订单详情页面
     *
     * @return ModelAndView
     * @author xiaoky
     */
    @RequestMapping(value = OrderMapping.SHOW_ORDER_DETAIL)
    public ModelAndView showOrderDetail(Integer orderId) {
        ModelAndView view = new ModelAndView(OrderMapping.SHOW_ORDER_DETAIL);
        OrderMain order = orderMainService.getOrderDetailById(orderId);
        QueryWrapper<OrderExpDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("order_code", order.getOrderCode());
        List<OrderExpDetail> expList = orderExpDetailService.list(wrapper);
        for (OrderExpDetail exp : expList) {
            if (exp.getWid() != null) {
                exp.setWarehouseName(warehouseService.getById(exp.getWid()).getName());
            } else {
                exp.setWarehouseName("——");
            }
            exp.setReceivedTypeName(ReceivedTypeEnums.getName(exp.getReceivedType()));
        }
        order.setExpList(expList);
        if (!CollectionUtils.isEmpty(expList)) {
            order.setExpDetail(expList.get(0));
        }
        view.addObject("order", order);
        return view;
    }

    /**
     * 订单发货操作
     *
     * @return RestResponse
     */
    @RequestMapping(value = OrderMapping.HANDLE_SEND_GOOD)
    @ResponseBody
    @SystemLog(methods = "商家端订单发货", module = "订单管理")
    public RestResponse handleSendGood(OrderExpDetail expDetail) {
        if (expDetail.getId() == null) {
            return GetRest.getFail("获取订单发货单失败");
        }
        OrderMain orderMain = orderMainService.getById(expDetail.getOrderId());
        if (orderMain == null) {
            return GetRest.getFail("该订单不存在");
        }
        CalcuUtils calUtil = CalcuUtils.getInstance();
        if (!calUtil.isEquals(OrderStatusEnums.NEED_SEND.getId(), orderMain.getOrderStatus())) {
            return GetRest.getFail("该订单不是待发货状态");
        }
        if (expDetail.getReceivedType() == null) {
            return GetRest.getFail("请选择发货方式");
        }
        if (calUtil.isEquals(ReceivedTypeEnums.EXP.getId(), expDetail.getReceivedType())) {
            if (StringUtils.isBlank(expDetail.getExpCode())) {
                return GetRest.getFail("请选择物流公司");
            }
            if (StringUtils.isBlank(expDetail.getExpNo())) {
                return GetRest.getFail("请填写快递单号");
            }
        }

        QueryWrapper<OrderDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("order_code", orderMain.getOrderCode()).eq("refund", StaticUtils.STATUS_APPLY);
        int count = orderDetailService.count(wrapper);
        if (count > 0) {
            return GetRest.getFail("当前订单包含正在退款中的商品，无法发货");
        }
        return orderMainService.handleOrderDeliver(expDetail);
    }

    /**
     * 商家主动退款
     *
     * @param orderCode
     * @return RestResponse
     */
    @RequestMapping(value = OrderMapping.HANDLE_BUS_REFUND)
    @ResponseBody
    @SystemLog(methods = "商家主动退款", module = "订单管理")
    public RestResponse handleBusRefund(String orderCode) {
        Integer loginId = BusinessSession.getLoginID(request);
        RestResponse result = orderRefundLogService.handleBusRefund(orderCode, loginId);
        return result;
    }

    /**
     * 订单退款管理
     *
     * @param page      分页
     * @param refundLog 订单退款数据查询条件
     * @return ModelAndView
     * @author xiaoky
     */
    @RequestMapping(value = OrderMapping.SHOW_ORDER_REFUND)
    public ModelAndView showOrderRefund(BasePage<OrderRefundLog> page, OrderRefundLog refundLog) {
        Integer bid = BusinessSession.getBid(request);
        ModelAndView view = new ModelAndView(OrderMapping.SHOW_ORDER_REFUND);
        QueryWrapper<OrderRefundLog> wrapper = new QueryWrapper<OrderRefundLog>();
        if (refundLog != null) {
            if (!StringUtils.isEmpty(refundLog.getOrderCode())) {
                wrapper.eq("order_code", refundLog.getOrderCode());
            }
            if (refundLog.getStatus() != null) {
                wrapper.eq("status", refundLog.getStatus());
            }
            wrapper.eq("bid", bid);
        }
        wrapper.orderByDesc("create_time");
        IPage<OrderRefundLog> refundPage = orderRefundLogService.queryRefunds(page, wrapper);
        view.addObject("pageInfo", refundPage);
        view.addObject("refund", refundLog);
        return view;
    }

    /**
     * 退款驳回操作
     *
     * @param refundId     退款数据id
     * @param rejectRemark 驳回理由
     * @return RestResponse
     * @author xiaoky
     */
    @RequestMapping(value = OrderMapping.HANDLE_REFUND_REJECT)
    @ResponseBody
    @SystemLog(methods = "退款驳回", module = "订单管理")
    public RestResponse handleRefundRefect(Integer refundId, String rejectRemark) {
        Integer loginId = BusinessSession.getLoginID(request);
        RestResponse result = orderRefundLogService.handleRefundRefect(refundId, rejectRemark, loginId);
        return result;
    }

    /**
     * 退款通过操作
     *
     * @param refundId 退款数据id
     * @return RestResponse
     * @author xiaoky
     */
    @RequestMapping(value = OrderMapping.HANDLE_REFUND_SUCCESS)
    @ResponseBody
    @SystemLog(methods = "退款通过", module = "订单管理")
    public RestResponse handleRefundSuccess(Integer refundId) {
        Integer loginId = BusinessSession.getLoginID(request);
        RestResponse result = orderRefundLogService.handleRefundSuccess(refundId, loginId);
        return result;
    }

    /**
     * 订单发货页面
     *
     * @param orderId 订单id
     * @return ModelAndView
     */
    @RequestMapping(value = OrderMapping.SHOW_ORDER_SEND)
    public ModelAndView showOrderSend(Integer orderId, Integer id) {
        CalcuUtils calUtil = CalcuUtils.getInstance();
        OrderExpDetail expDetail = orderExpDetailService.getById(id);
        if (expDetail == null) {
            throw new ThrowPageException("该发货单信息异常");
        }
        ModelAndView view = new ModelAndView(OrderMapping.SHOW_ORDER_SEND);
        // 发货方式
        List<ReceivedTypeEnums> receivedTypeList = ReceivedTypeEnums.queryList();
        // 快递公司列表
        List<OrderBasicExp> expList = orderBasicExpService.queryBasicExp();
        //发货单所有的商品详情ID集合
        List<String> allList = new ArrayList<>(Arrays.asList(expDetail.getDetailIds().split(",")));
        if (StringUtils.isNotBlank(expDetail.getRefundDetailId())
                && !calUtil.isEquals(expDetail.getRefundStatus(), StaticUtils.STATUS_YES)) {
            //发货单已退款的商品详情ID集合
            List<String> refundList = new ArrayList<>(Arrays.asList(expDetail.getRefundDetailId().split(",")));
            allList.removeAll(refundList);
        }
        List<PropertiesVo> detailList = null;

        OrderMain orderMain = orderMainService.getById(orderId);
        if (!calUtil.isEquals(orderMain.getOrderType(), OrderTypeEnums.LOGISTICS.getId())) {
            detailList = new ArrayList<>();
            for (String s : allList) {
                PropertiesVo vo = new PropertiesVo();
                ProSkuDetail sku = proSkuDetailService.getById(Integer.parseInt(s));
                ProcMain procMain = procMainService.selectOneByProCode(sku.getProCode());
                vo.setName(procMain.getProCode() + "|" + procMain.getProName());
                vo.setValue(sku.getSpecName());
                detailList.add(vo);
            }
        }

        view.addObject("orderId", orderId);
        view.addObject("expList", expList);
        view.addObject("receivedTypeList", receivedTypeList);
        view.addObject("expDetailId", id);
        view.addObject("detailList", detailList);
        return view;
    }

    /**
     * 通过订单编号查询物流信息
     *
     * @param orderCode 订单编号
     * @return 物流数据信息
     */
    @RequestMapping(value = OrderMapping.QUERY_EXP_MSG)
    @ResponseBody
    public RestResponse queryExpMsg(String orderCode) {
        QueryWrapper<OrderExpDetail> wrapper = new QueryWrapper<>();
        //wrapper.eq("order_code",orderCode).eq("id",expDetailId);
        OrderExpDetail expDetail = orderExpDetailService.getOne(wrapper);
        if (expDetail != null && CalcuUtils.getInstance().isEquals(expDetail.getReceivedType(), ReceivedTypeEnums.EXP.getId())) {
            String expMsg = orderExpDetailService.handleLiveExpData(expDetail.getId());
            List<ExpDetailVo> expMsgList = JSONArray.parseArray(expMsg, ExpDetailVo.class);
            if (expMsgList != null && expMsgList.size() > 0) {
                Collections.reverse(expMsgList);
            }
            expDetail.setExpDetailList(expMsgList);
        }
        return GetRest.getSuccess("", expDetail);
    }

    /**
     * 显示订单物流信息
     *
     * @param orderCode 订单编号
     * @return
     * @author xiaoky
     */
    @RequestMapping(value = OrderMapping.SHOW_ORDER_EXP_MSG)
    public ModelAndView showExpMsg(String orderCode) {
        ModelAndView view = new ModelAndView(OrderMapping.SHOW_ORDER_EXP_MSG);
        QueryWrapper<OrderExpDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("order_code", orderCode);
        List<OrderExpDetail> expList = orderExpDetailService.list(wrapper);
        for (OrderExpDetail expDetail : expList) {
            if (expDetail != null && CalcuUtils.getInstance().isEquals(expDetail.getReceivedType(), ReceivedTypeEnums.EXP.getId())) {
                String expMsg = orderExpDetailService.handleLiveExpData(expDetail.getId());
                List<ExpDetailVo> expMsgList = JSONArray.parseArray(expMsg, ExpDetailVo.class);
                if (expMsgList != null && expMsgList.size() > 0) {
                    Collections.reverse(expMsgList);
                }
                expDetail.setExpDetailList(expMsgList);
            }
        }
        view.addObject("expList", expList);
        return view;
    }

    /* 发货部分 */

    /**
     * 发货列表页
     *
     * @return org.springframework.web.servlet.ModelAndView
     * @author leehao
     */
    @RequestMapping(value = OrderMapping.SHOW_ORDER_EXP_LIST)
    public ModelAndView showOrderExpList() {
        ModelAndView view = new ModelAndView(OrderMapping.SHOW_ORDER_EXP_LIST);
        return view;
    }

    /**
     * 发货列表数据
     *
     * @param page      分页
     * @param expDetail 查询
     * @return com.sxbbc.common.basics.rest.RestResponse
     * @author leehao
     */
    @RequestMapping(value = OrderMapping.QUERY_ORDER_EXP_LIST)
    @ResponseBody
    public com.sxbbc.common.basics.rest.RestResponse queryOrderExp(BasePage<OrderExpDetail> page,
                                                                   OrderExpDetail expDetail,
                                                                   HttpServletRequest request) {
        Integer bid = BusinessSession.getBid(request);
        expDetail.setBid(bid);
        orderExpDetailService.queryOrderExpList(page, expDetail);
        return RestFactory.success(page.getRecords(), page.getTotal());
    }

    /**
     * 显示订单详情显示修改物流单号页面
     *
     * @return
     * @author xiaoky
     */
    @RequestMapping(value = OrderMapping.SHOW_ORDER_UPDATE_EXP)
    public ModelAndView showOrderUpdateExp(Integer orderId, Integer id) {
        ModelAndView view = new ModelAndView(OrderMapping.SHOW_ORDER_UPDATE_EXP);
        CalcuUtils calUtil = CalcuUtils.getInstance();
        OrderExpDetail expDetail = orderExpDetailService.getById(id);
        if (expDetail == null) {
            throw new ThrowPageException("该发货单信息异常");
        }
        // 发货方式
        List<ReceivedTypeEnums> receivedTypeList = ReceivedTypeEnums.queryList();
        // 快递公司列表
        List<OrderBasicExp> expList = orderBasicExpService.queryBasicExp();
        //发货单所有的商品详情ID集合
        List<String> allList = new ArrayList<>(Arrays.asList(expDetail.getDetailIds().split(",")));
        if (StringUtils.isNotBlank(expDetail.getRefundDetailId())
                && !calUtil.isEquals(expDetail.getRefundStatus(), StaticUtils.STATUS_YES)) {
            //发货单已退款的商品详情ID集合
            List<String> refundList = new ArrayList<>(Arrays.asList(expDetail.getRefundDetailId().split(",")));
            allList.removeAll(refundList);
        }
        List<PropertiesVo> detailList = new ArrayList<>();
        for (String s : allList) {
            PropertiesVo vo = new PropertiesVo();
            ProSkuDetail sku = proSkuDetailService.getById(Integer.parseInt(s));
            ProcMain procMain = procMainService.selectOneByProCode(sku.getProCode());
            vo.setName(procMain.getProCode() + "|" + procMain.getProName());
            vo.setValue(sku.getSpecName());
            detailList.add(vo);
        }
        view.addObject("orderId", orderId);
        view.addObject("expList", expList);
        view.addObject("receivedTypeList", receivedTypeList);
        view.addObject("expDetailId", id);
        view.addObject("expNo", expDetail.getExpNo());
        view.addObject("expCode", expDetail.getExpCode());
        view.addObject("detailList", detailList);
        return view;
    }

    /**
     * 处理订单修改发货单
     *
     * @param expDetail
     * @return
     * @author xiaoky
     */
    @RequestMapping(value = OrderMapping.HANDLE_ORDER_UPDATE_EXP)
    @ResponseBody
    public RestResponse handleUpdateSendCode(OrderExpDetail expDetail) {
        if (expDetail.getId() == null) {
            return GetRest.getFail("获取订单发货单失败");
        }
        OrderMain orderMain = orderMainService.getById(expDetail.getOrderId());
        if (orderMain == null) {
            return GetRest.getFail("该订单不存在");
        }

        //订单发货单
        OrderExpDetail orderExpDetail = orderExpDetailService.getById(expDetail.getId());
        if (orderExpDetail == null) {
            return GetRest.getFail("获取订单发货单失败");
        }
        CalcuUtils calcuUtils = CalcuUtils.getInstance();
        // 规则——限制  物流发货，已发货状态订单或者物流已发货
        if (!(calcuUtils.isEquals(orderExpDetail.getReceivedType(), ReceivedTypeEnums.EXP.getId())
                && (calcuUtils.isEquals(orderMain.getOrderStatus(), OrderStatusEnums.HAS_SEND.getId())
                || (calcuUtils.isEquals(orderMain.getOrderStatus(), OrderStatusEnums.NEED_SEND.getId())
                && calcuUtils.isEquals(orderExpDetail.getStatus(), StaticUtils.STATUS_YES))))) {
            return GetRest.getFail("当前状态不可以修改");
        }
        CalcuUtils calUtil = CalcuUtils.getInstance();
        if (calUtil.isEquals(ReceivedTypeEnums.EXP.getId(), expDetail.getReceivedType())) {
            if (StringUtils.isBlank(expDetail.getExpCode())) {
                return GetRest.getFail("请选择物流公司");
            }
            if (StringUtils.isBlank(expDetail.getExpNo())) {
                return GetRest.getFail("请填写快递单号");
            }
        }
        return orderMainService.handleUpdateSendCode(expDetail);
    }

    /**
     * 修改订单收货地址显示页面
     *
     * @param orderCode
     * @return
     * @author xiaoky
     */
    @RequestMapping(value = OrderMapping.SHOW_ORDER_RECEIVE)
    public ModelAndView showOrderReceive(String orderCode) {
        ModelAndView view = new ModelAndView(OrderMapping.SHOW_ORDER_RECEIVE);
        QueryWrapper<OrderExpDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("order_code", orderCode);
        List<OrderExpDetail> expList = orderExpDetailService.list(wrapper);
        if (CollectionUtils.isEmpty(expList)) {
            throw new ThrowPageException("修改失败");
        }
        OrderExpDetail exp = orderExpDetailService.getById(expList.get(0).getId());
        if (exp == null) {
            throw new ThrowPageException("修改失败");
        }
        Address address = new Address();
        address.setPid(StaticUtils.ADDRESS_COUNTRY);
        List<Address> proList = addressService.queryAddressByParentId(address);
        List<Address> cityList = new ArrayList<>();
        List<Address> areaList = new ArrayList<>();
        Integer proId = null;
        Integer cityId = null;
        Integer areaId = null;
        String addrids = exp.getAddrids();
        if (!StringUtils.isBlank(addrids)) {
            try {
                List<String> ids = Arrays.asList(addrids.split(","));
                proId = Integer.parseInt(ids.get(0));
                address.setPid(proId);
                cityList = addressService.queryAddressByParentId(address);
                cityId = Integer.parseInt(ids.get(1));
                address.setPid(cityId);
                areaList = addressService.queryAddressByParentId(address);
                areaId = Integer.parseInt(ids.get(2));
            } catch (NumberFormatException e) {
                throw new ThrowPageException("修改错误");
            }
        }
        exp.setProId(proId);
        exp.setCityId(cityId);
        exp.setAreaId(areaId);
        view.addObject("exp", exp);
        view.addObject("orderCode", orderCode);
        view.addObject("proList", proList);
        view.addObject("cityList", cityList);
        view.addObject("areaList", areaList);
        return view;
    }

    /**
     * 修改收货地址
     *
     * @param expDetail
     * @return
     * @author xiaoky
     */
    @RequestMapping(value = OrderMapping.EDIT_ORDER_RECEIVE)
    @ResponseBody
    public RestResponse editOrderReceive(OrderExpDetail expDetail) {
        if (expDetail.getProId() == null || expDetail.getCityId() == null || expDetail.getAreaId() == null) {
            return GetRest.getFail("请选择地区");
        }
        if (StringUtils.isBlank(expDetail.getAddressDetail())) {
            return GetRest.getFail("请输入详细地址");
        }
        return orderMainService.editOrderReceive(expDetail);
    }

}
